package com.xuecheng.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.learning.feignclient.ContentServiceClient;
import com.xuecheng.learning.mapper.XcChooseCourseMapper;
import com.xuecheng.learning.mapper.XcCourseTablesMapper;
import com.xuecheng.learning.model.dto.MyCourseTableParams;
import com.xuecheng.learning.model.dto.XcChooseCourseDto;
import com.xuecheng.learning.model.dto.XcCourseTablesDto;
import com.xuecheng.learning.model.po.XcChooseCourse;
import com.xuecheng.learning.model.po.XcCourseTables;
import com.xuecheng.learning.service.MyCourseTablesService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class MyCourseTablesServiceImpl implements MyCourseTablesService {

    @Autowired
    private XcChooseCourseMapper chooseCourseMapper;

    @Autowired
    private XcCourseTablesMapper courseTablesMapper;

    @Autowired
    private ContentServiceClient contentServiceClient;

    /**
     * 添加选课
     * @param userId 用户id
     * @param courseId 课程id
     * @return
     */
    @Transactional
    @Override
    public XcChooseCourseDto  addChooseCourse(String userId, Long courseId) {
        //选课调用内容管理，查询课程的收费规则
        CoursePublish coursepublish = contentServiceClient.getCoursepublish(courseId);
        if(coursepublish == null){
            XueChengPlusException.cast("课程不存在");
        }
        //收费规则
        String charge = coursepublish.getCharge();

        XcChooseCourse xcChooseCourse = null;
        if(charge.equals("201000")){
            //如果课程免费，则向选课记录表
            xcChooseCourse = addFreeCourse(userId, coursepublish);
            //向我的课程表插入数据
            XcCourseTables xcCourseTables = addCourseTables(xcChooseCourse);

        }else{
            //如果课程收费，则向选课记录表插入数据
            xcChooseCourse = addChargeCourse(userId, coursepublish);
        }
        //最后判断学生的学习资格
        XcCourseTablesDto learningStatus = getLearningStatus(userId, courseId);

        //构造返回值
        XcChooseCourseDto xcChooseCourseDto = new XcChooseCourseDto();
        BeanUtils.copyProperties(xcChooseCourse, xcChooseCourseDto);
        xcChooseCourseDto.setLearnStatus(learningStatus.getLearnStatus());
        return xcChooseCourseDto;
    }

    /**
     * 判断学习资格
     * @param userId
     * @param courseId
     * @return
     */
    @Override
    public XcCourseTablesDto getLearningStatus(String userId, Long courseId) {
        //最终返回的结果
        XcCourseTablesDto xcCourseTablesDto = new XcCourseTablesDto();
        //查询我的课程表，查不到说明没有选课
        XcCourseTables xcCourseTables = courseTablesMapper.selectOne(new LambdaQueryWrapper<XcCourseTables>().eq(XcCourseTables::getUserId, userId).eq(XcCourseTables::getCourseId, courseId));
        if(xcCourseTables == null){
            //没有选课或选课后没有支付
            xcCourseTablesDto.setLearnStatus("702002");
            return xcCourseTablesDto;
        }

        //如果查到了，判断是否过期
        boolean before = xcCourseTables.getValidtimeEnd().isBefore(LocalDateTime.now());
        if(before){
            //过期,需要重新申请和支付
            BeanUtils.copyProperties(xcCourseTables, xcCourseTablesDto);
            xcCourseTablesDto.setLearnStatus("702003");
            return xcCourseTablesDto;
        }else{
            //正常学习
            BeanUtils.copyProperties(xcCourseTables, xcCourseTablesDto);
            xcCourseTablesDto.setLearnStatus("702001");
            return xcCourseTablesDto;
        }
    }

    /**
     * 添加免费课程，插入到选课记录表
     * @param userId
     * @param coursePublish
     * @return
     */
    private XcChooseCourse addFreeCourse(String userId, CoursePublish coursePublish){
        //判断选课记录表中是否已经存在数据
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XcChooseCourse::getUserId, userId).eq(XcChooseCourse::getCourseId, coursePublish.getId())
                .eq(XcChooseCourse::getOrderType, "700001").eq(XcChooseCourse::getStatus, "701001");
        List<XcChooseCourse> xcChooseCourses = chooseCourseMapper.selectList(queryWrapper);
        if(xcChooseCourses.size() > 0){
            return xcChooseCourses.get(0);
        }

        //添加选课记录信息
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(coursePublish.getId());
        xcChooseCourse.setCourseName(coursePublish.getName());
        xcChooseCourse.setCoursePrice(0f);//免费课程价格为0
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(coursePublish.getCompanyId());
        xcChooseCourse.setOrderType("700001");//免费课程
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setStatus("701001");//选课成功

        xcChooseCourse.setValidDays(365);//免费课程默认365
        xcChooseCourse.setValidtimeStart(LocalDateTime.now());
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));
        chooseCourseMapper.insert(xcChooseCourse);

        return xcChooseCourse;
    }

    /**
     * 添加课程到我的课程表
     * @param xcChooseCourse
     * @return
     */
    private XcCourseTables addCourseTables(XcChooseCourse xcChooseCourse){
        //选课成功了才可以向我的课程表插入数据
        String status = xcChooseCourse.getStatus();
        if(!status.equals("701001")){
            XueChengPlusException.cast("选课没有成功，无法加入到我的课程表");
        }

        //查询数据库中是否已经存在这条数据
        LambdaQueryWrapper<XcCourseTables> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XcCourseTables::getCourseId, xcChooseCourse.getCourseId())
                .eq(XcCourseTables::getUserId, xcChooseCourse.getUserId());
        XcCourseTables xcCourseTables = courseTablesMapper.selectOne(queryWrapper);
        if(xcCourseTables != null){
            return xcCourseTables;
        }
        xcCourseTables = new XcCourseTables();
        BeanUtils.copyProperties(xcChooseCourse, xcCourseTables);
        xcCourseTables.setChooseCourseId(xcChooseCourse.getId());
        xcCourseTables.setCourseType(xcChooseCourse.getOrderType());
        xcCourseTables.setUpdateDate(LocalDateTime.now());
        courseTablesMapper.insert(xcCourseTables);

        return xcCourseTables;
    }

    /**
     * 添加收费课程到选课记录表
     * @param userId
     * @param coursePublish
     * @return
     */
    private XcChooseCourse addChargeCourse(String userId,CoursePublish coursePublish ){
        //判断选课记录表中是否已经存在数据
        LambdaQueryWrapper<XcChooseCourse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XcChooseCourse::getUserId, userId).eq(XcChooseCourse::getCourseId, coursePublish.getId())
                .eq(XcChooseCourse::getOrderType, "700002").eq(XcChooseCourse::getStatus, "701002");
        List<XcChooseCourse> xcChooseCourses = chooseCourseMapper.selectList(queryWrapper);
        if(xcChooseCourses.size() > 0){
            return xcChooseCourses.get(0);
        }

        //添加选课记录信息
        XcChooseCourse xcChooseCourse = new XcChooseCourse();
        xcChooseCourse.setCourseId(coursePublish.getId());
        xcChooseCourse.setCourseName(coursePublish.getName());
        xcChooseCourse.setCoursePrice(coursePublish.getPrice());//免费课程价格为0
        xcChooseCourse.setUserId(userId);
        xcChooseCourse.setCompanyId(coursePublish.getCompanyId());
        xcChooseCourse.setOrderType("700002");//收费课程
        xcChooseCourse.setCreateDate(LocalDateTime.now());
        xcChooseCourse.setStatus("701002");//待支付

        xcChooseCourse.setValidDays(365);//免费课程默认365
        xcChooseCourse.setValidtimeStart(LocalDateTime.now());
        xcChooseCourse.setValidtimeEnd(LocalDateTime.now().plusDays(365));
        chooseCourseMapper.insert(xcChooseCourse);

        return xcChooseCourse;
    }

    /**
     * 保存选课成功状态
     * @param chooseCourseId
     * @return
     */
    @Override
    public boolean saveChooseCourseSuccess(String chooseCourseId) {
        //根据选课id查询选课表，判断是否存在
        XcChooseCourse xcChooseCourse = chooseCourseMapper.selectById(chooseCourseId);
        if(xcChooseCourse == null){
            log.debug("接收购买课程的消息，根据选课id从数据库找不到选课记录，选课id:{}", chooseCourseId);
            return false;
        }

        //选课状态
        String status = xcChooseCourse.getStatus();
        //判断是否是未支付
        if(status.equals("701002")){
            //更新选课记录表的状态为已支付
            xcChooseCourse.setStatus("701001");
            int i = chooseCourseMapper.updateById(xcChooseCourse);
            if(i <= 0){
                log.debug("添加选课记录失败:{}", xcChooseCourse);
                XueChengPlusException.cast("添加选课记录失败:{}");
            }

            //向我的课程表插入数据
            XcCourseTables xcCourseTables = addCourseTables(xcChooseCourse);
            return true;
        }
        return false;
    }

    /**
     * 我的课程表
     * @param params
     * @return
     */
    @Override
    public PageResult<XcCourseTables> mycoursetables(MyCourseTableParams params) {
        //用户id
        String userId = params.getUserId();

        //当前页码
        int pageNo = params.getPage();

        //每页记录数
        int size = params.getSize();

        Page<XcCourseTables> page = new Page<>(pageNo, 4);
        LambdaQueryWrapper<XcCourseTables> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XcCourseTables::getUserId, userId);
        //查询数据
        Page<XcCourseTables> result = courseTablesMapper.selectPage(page, queryWrapper);

        //封装数据
        //数据列表
        List<XcCourseTables> records = result.getRecords();
        //总记录数
        long total = result.getTotal();
        PageResult<XcCourseTables> pageResult = new PageResult<>(records, total, pageNo, 4);
        return pageResult;
    }
}
